package com.ktjiaoyu.server.config.security;

import com.ktjiaoyu.server.service.impl.UserDetailServiceImpl;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.ObjectPostProcessor;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.builders.WebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.config.http.SessionCreationPolicy;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.security.web.access.intercept.FilterSecurityInterceptor;
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;

import javax.annotation.Resource;

@Configuration
public class SecurityConfig extends WebSecurityConfigurerAdapter {
    @Resource
    RestAuthorizationEntryPoint restAuthorizationEntryPoint;
    @Resource
    RestfulAccessDeniedHandler restfulAccessDeniedHandler;
    @Resource
    JwtAuthencationTokenFilter jwtAuthencationTokenFilter;
    @Resource
    UserDetailServiceImpl userDetailService;
    @Resource
    CustomUrlDecisionManager customUrlDecisionManager;
    @Resource
    CustomFilter customFilter;

    @Bean
    public PasswordEncoder passwordEncoder(){
        return new BCryptPasswordEncoder();
    }

    @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {
        auth.userDetailsService(userDetailService).passwordEncoder(passwordEncoder());
    }

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        //授权配置
        http.authorizeRequests()
                //指定login这个地址；所有人都能访问
                .antMatchers(
                        "/login",
                        "/logout"
                ).permitAll()
                //其他的地址；必须登录才能访问
                .anyRequest().authenticated()
                .withObjectPostProcessor(new ObjectPostProcessor<FilterSecurityInterceptor>() {
                    @Override
                    public <O extends FilterSecurityInterceptor> O postProcess(O o) {
                        o.setAccessDecisionManager(customUrlDecisionManager);
                        o.setSecurityMetadataSource(customFilter);
                        return o;
                    }
                });

        //关闭防火墙
        http.csrf().disable();

        //不需要session
        http.sessionManagement()
                .sessionCreationPolicy(SessionCreationPolicy.STATELESS);

        //禁用缓存
        http.headers().cacheControl();

        //未授权，未登录的异常处理
        http.exceptionHandling()
                //指定未授权的处理对象
                .accessDeniedHandler(restfulAccessDeniedHandler)
                //指定未登录的处理对象
                .authenticationEntryPoint(restAuthorizationEntryPoint);


        //配置token解析过滤器
        http.addFilterBefore(jwtAuthencationTokenFilter,
                UsernamePasswordAuthenticationFilter.class);

    }

    @Override
    public void configure(WebSecurity web) throws Exception {
        web.ignoring().antMatchers(
                "/login",
                "/logout",
                "/css/**",
                "/js/**",
                "/index.html",
                "favicon.ico",
                "/doc.html",
                "/swagger-ui.html",
                "/webjars/**",
                "/swagger-resources/**",
                "/v2/api-docs/**",
                "/captcha"
        );
    }

}
